package git.soulbgm.utils;

import git.soulbgm.constant.Constants;
import git.soulbgm.pojo.CmdResult;
import git.soulbgm.pojo.TimeSyncInfo;
import org.apache.commons.net.ntp.NTPUDPClient;
import org.apache.commons.net.ntp.TimeInfo;

import java.io.IOException;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;

/**
 * 同步时间工具类
 *
 * @author SoulBGM
 * @date 2021-09-23
 */
public class NtpdateUtil {

    /**
     * 同步失败时的消息 接收超时
     */
    private final static String RECEIVE_TIMED_OUT = "Receive timed out";
    /**
     * NTP客户端
     */
    private final static NTPUDPClient CLIENT;

    static {
        CLIENT = new NTPUDPClient();
        CLIENT.setDefaultTimeout(10000);
        try {
            CLIENT.open();
        } catch (SocketException e) {
            e.printStackTrace();
        }
    }

    /**
     * 同步时间
     *
     * @param ntpServerAddress Ntp服务器地址
     * @return {@link TimeSyncInfo}
     * @throws IOException IO异常
     */
    public static TimeSyncInfo ntpdate(InetAddress ntpServerAddress) throws IOException {
        TimeSyncInfo info = new TimeSyncInfo();
        String ip = ntpServerAddress.getHostAddress();
        info.setNtpIp(ip);
        info.setOffsetSeconds(0D);
        info.setStatus(Constants.NTP_FAIL);
        TimeInfo timeInfo;
        try {
            timeInfo = CLIENT.getTime(ntpServerAddress);
        } catch (SocketTimeoutException e) {
            if (e.getMessage().contains(RECEIVE_TIMED_OUT)) {
                info.setStatus(Constants.NTP_UNAVAILABLE);
            }
            return info;
        }
        timeInfo.computeDetails();
        Long offset = timeInfo.getOffset();
        long updateTime = System.currentTimeMillis() + offset;
        CmdResult result = CmdUtil.updateSystemDateTime(updateTime);
        if (result.isSuccess()) {
            info.setOffsetSeconds(Arith.div(offset, 1000, 6));
            info.setStatus(Constants.NTP_SUCCESS);
        }
        return info;
    }

}
